package com.cff.springbootwork.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class OperateLogAspect {
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Pointcut("execution(* com.cff.springbootwork.aspectj.service.BusinessService.*(..)) && !execution(* com.cff.springbootwork.aspectj.service.BusinessService.getTest*(..)) ")
	private void log() {
	}

	@Before("log()")
	public void beforeMethod(JoinPoint joinPoint) {
		String methodName = joinPoint.getSignature().getName();
		joinPoint.getArgs();
		logger.info("方法为:" + methodName + ", 这是一个前置测试 ");
	}

	@After("execution(* com.cff.springbootwork.aspectj.service.BusinessService.*(..))")
	public void afterMethod(JoinPoint joinPoint) {
		String methodName = joinPoint.getSignature().getName();
		logger.info("方法为:" + methodName + ", 这是一个后置测试 ");
	}
	
	@Around("execution(* com.cff.springbootwork.aspectj.service.AsyncTestService.getSyncTestInfo(..))")
	public Object test(ProceedingJoinPoint joinPoint) throws Throwable {
		String methodName = joinPoint.getSignature().getName();
		logger.info("方法为:" + methodName + ", 测水水水水水水水水水水 ");
		Object obj;
		try {
			obj = joinPoint.proceed();
			return obj;
		} catch (Throwable e) {
			logger.info("方法为:" + methodName + ",异常 ");
			throw e;
		}
	}

	@AfterReturning(value = "log()", returning = "result")
	public void afterReturning(JoinPoint point, Object result) {
		String methodName = point.getSignature().getName();
		logger.info("方法为：" + methodName + "，目标方法执行结果为：" + result);
	}

	@Around("log()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		logger.info("请求参数：{}", joinPoint.getArgs());
		Object[] arr = joinPoint.getArgs();
		Integer type = (Integer) arr[1];
		logger.info("请求类型：{}", type);
		long startTime = System.currentTimeMillis();
		Object obj = joinPoint.proceed();
		long timeTaken = System.currentTimeMillis() - startTime;
		logger.info("执行时间：{}", timeTaken);
		return obj;
	}
}